<template>
  <div class="div-form-contents">
    <!-- 拖拽为空时显示 -->
    <div class="null-form" v-if="formData.list.length === 0">
      <a-icon type="plus-square" class="null-icon" />
      <div>从左侧拖拽组件</div>
    </div>
    <a-form-model :label-col="{ span: formData.config.labelCol }" :wrapper-col="{ span: formData.config.wrapperCol }" :layout="formData.config.layout" :colon="formData.config.colon" :labelAlign="formData.config.labelAlign" class="mgt-10 mgl-30 mgr-30">
      <draggable v-model="formData.list" group="form" @add="handleWidgetAdd" class="form-content">
        <div v-for="(item, index) in formData.list" :class="{ active: item.field && selectData.field === item.field }" :key="index" class="form-item pd-10" @click="handleSelectWidget(item)">
          <a-form-model-item :label="item.showTitle && item.title" :required="item.required">
            <FormItems :eleItem="item" />
            <div class="desc" v-if="item.desc">{{ item.desc }}</div>
          </a-form-model-item>
          <div class="tags">
            <div class="view-operations align-items-center flex">
              <!-- 复制 -->
              <a-tag @click.stop="copy(item, index)" color="cyan" class="border-0 mg-0">
                <a-icon type="copy" />
              </a-tag>
              <a-divider type="vertical"></a-divider>
              <!-- 移动 -->
              <a-tag class="movetag border-0 mg-0" color="purple">
                <a-icon type="drag" />
              </a-tag>
              <a-divider type="vertical"></a-divider>
              <!-- 删除 -->
              <a-tag @click="remove(index)" color="red" class="border-0 mg-0">
                <a-icon type="delete" />
              </a-tag>
            </div>
          </div>
        </div>
      </draggable>
    </a-form-model>
  </div>
</template>
<script>
import FormItems from './form-items.vue'
export default {
  name: 'contents',
  props: ['formData', 'select'],
  components: {
    FormItems
  },
  watch: {
    selectData: {
      handler(data) {
        this.$emit('update:select', data)
      }
    }
  },
  data() {
    return {
      selectData: this.select
    }
  },
  methods: {
    // 拖拽完成事件
    handleWidgetAdd(e) {
      // 获取当前拖拽的元素在放置栏中的下标
      const newIndex = e.newIndex
      // 设置元素唯一key值
      const key = `${Date.parse(new Date())}_${Math.ceil(
        Math.random() * 99999
      )}`
      this.formData.list[newIndex].field = 'field' + key
      // 拖拽完成后往当前元素的options添加remoteFunc，options平级添加key，model
      this.$set(this.formData.list, newIndex, {
        // 解构语法解构当前数据达到深拷贝效果，改变数据不会影响原有数据
        ...this.formData.list[newIndex],
        // 新增属性key
        key,
        newIndex, // 创建排序
        index: newIndex // 页面排序
      })
      // 深拷贝数据，使重复组件之前相互不受影响
      let data = JSON.parse(JSON.stringify(this.formData.list[newIndex]))
      data = this.setDefaultValue(data)
      this.$set(this.formData.list, newIndex, data)
      // 获取拖拽的表单数据,子父组件数据双向绑定实时改变右侧配置
      this.selectData = this.formData.list[newIndex]
      // 给所有数据重新进行页面排序
      this.formData.list = this.formData.list.map((item, index) => {
        return {
          ...item,
          index: index
        }
      })
      // 重新选中
      this.selectData = this.formData.list?.filter(
        (item) => item.field === this.selectData.field
      )[0]
    },
    // 初始化
    setDefaultValue(data) {
      let type = ['timePicker', 'datePicker', 'dateTimePicker']
      // 时间日期初始化
      if (type.includes(data.type)) {
        data.options.defaultValue = this.$moment(
          new Date(),
          data.options.format
        )
      }
      return data
    },
    // 选中组件
    handleSelectWidget(item) {
      this.selectData = item
      this.$emit('selectValue', item);
    },
    // 复制
    copy(item, index) {
      let data = JSON.parse(JSON.stringify(item))
      const key = `${Date.parse(new Date())}_${Math.ceil(
        Math.random() * 99999
      )}`
      data.field = 'field' + key
      data.key = key
      this.$nextTick(() => {
        this.formData.list.splice(index + 1, 0, data)
        this.formData.list = this.formData.list.map((item, index) => {
          return {
            ...item,
            index: index
          }
        })
        this.selectData = data
      })
    },
    // 删除
    remove(index) {
      let that = this
      this.$confirm({
        title: '删除提示',
        content: '是否确定删除该组件',
        okText: '确认',
        cancelText: '取消',
        onOk() {
          that.removeWidgetElement(index)
        },
        onCancel() {}
      })
    },
    // 删除组件方法
    removeWidgetElement(index) {
      if (this.formData.list.length - 1 === index) {
        if (index === 0) {
          this.selectData = {
            key: null,
            field: ''
          }
        } else {
          this.selectData = this.formData.list[index - 1]
        }
      } else {
        this.selectData = this.formData.list[index + 1]
      }
      this.$nextTick(() => {
        this.formData.list.splice(index, 1)
        this.formData.list = this.formData.list.map((item, index) => {
          return {
            ...item,
            index: index
          }
        })
      })
    }
  }
}
</script>
<style lang="less" scoped>
.div-form-contents {
  position: relative;
  height: 100%;
  overflow: auto;
  background-color: #fff;
  .form-content {
    min-height: calc(100vh - 253px);
    .form-item {
      margin-top: 10px;
      background-color: #eef4ff;
      .desc {
        word-break: break-all;
        line-height: 18px;
        font-size: 14px;
        color: #9b9b9b;
      }
    }
    .tags {
      display: flex;
      justify-content: flex-end;
    }
    .view-operations {
      display: none;
    }
    .active .view-operations {
      height: 36px;
      padding: 0 10px;
      display: flex;
      cursor: pointer;
      border-radius: 18px;
      border: 1px solid #dfdfdf;
      background-color: #fff;
    }
  }
  .null-form {
    position: absolute;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    color: #999999;
    .null-icon {
      display: block;
      font-size: 93px;
    }
  }
}
</style>
